module alayout
import StdEnv, japi

/* Flow Buttons and fields provide practical tools to create 
   a simple layout. The result is not very good though. 
   The example shows also how to handle the cursor. */

:: State = { frame::!Framer, upper::!TDev, lower::!TDev, 
             factorial::!TDev, field::!TDev}

fat n
  | n < 1= 1
  | otherwise= n* (fat (n-1))
  
strfac dv
  # txt= (jgetText dv)
  # ans= toString(fat(toInt txt ))
= jsetText dv ("Factorial: "+++ans)

Start world
  # (js, world) = begin_japi world                       
    (frm, js) = jnewFrame FLOW "Uppercase" js     
    
    (frm, js) = jverticalLayout frm js
    
    (frm, js) = vGap frm 60 js
    
    (panel1, js)= jnewPanel FLOW frm js
    (panel1, js)= jhorizontalLayout panel1 js
    (panel2, js)= jnewPanel FLOW frm js
    (panel2, js)= jhorizontalLayout panel2 js
    
    (txt, js) = jnewField  FLOW 30 panel1 js             
    (factorialBt, js) = jnewButton FLOW "Factorial" panel1 js
    (upperbt, js) = jnewButton  FLOW "UpperCase" panel2 js
    (lowerbt, js) = jnewButton  FLOW "LowerCase" panel2 js
    (panel2, js)= hGap panel2 70 js
    (panel2, js)= jsetcursor J_CROSSHAIR panel2 js
    (frm, js) = jpack frm js
    (frm, js) = jshow frm js
    s= { frame= frm, upper= upperbt, lower= lowerbt, 
         factorial= factorialBt, field= txt}                             
    js= loop s js                                 
  = end_japi js world                                    
where
    loop :: !State !JapiState -> JapiState
    loop s js
       # (na, js) = jnextaction js               
       | na== (act s.frame) = jquit js                      
       | na== (act s.factorial) 
              = loop {s&field= (strfac s.field)}  js
       | na== (act s.upper)
              = loop {s&field= (apply toUpper s.field)} js  
       | na== (act s.lower)
              = loop {s&field= (apply toLower s.field)} js    
       | otherwise= loop s js               
       
    apply fn txt = jsetText txt {fn c \\ c <-: (jgetText txt)}
    